package com.yuyou.fn.analyze.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.github.wens.framework.service.impl.SuperServiceImpl;
import com.github.wens.mybatisplus.examples.Example;
import com.github.wens.mybatisplus.plugins.Page;
import com.yuyou.fn.analyze.entity.TeacherTarget;
import com.yuyou.fn.analyze.mapper.TeacherTargetMapper;
import com.yuyou.fn.analyze.service.ITeacherTargetService;
import com.yuyou.fn.analyze.vo.TargetTypeDetailVo;
import com.yuyou.fn.analyze.vo.TeacherTargetDetailVo;
import com.yuyou.fn.analyze.vo.TeacherTargetResultVo;
import com.yuyou.fn.analyze.vo.TeacherTargetVo;
import com.yuyou.fn.common.exception.BusException;
import com.yuyou.fn.common.service.ISiteConfigService;
import com.yuyou.fn.common.util.BeanUtils;
import com.yuyou.fn.common.util.TimeUtils;
import com.yuyou.fn.common.util.Utils;
import com.yuyou.fn.educational.entity.Period;
import com.yuyou.fn.educational.entity.Teacher;
import com.yuyou.fn.educational.service.ICourseClassService;
import com.yuyou.fn.educational.service.IPeriodService;
import com.yuyou.fn.educational.service.ITeacherService;
import com.yuyou.fn.educational.vo.TeacherQueryVo;
import com.yuyou.fn.platform.permission.DataPermission;
import com.yuyou.fn.platform.service.IBusTeamService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 *
 * TeacherTarget 表数据服务层接口实现类
 *
 */
@Service
public class TeacherTargetServiceImpl extends SuperServiceImpl<TeacherTargetMapper, TeacherTarget,String> implements ITeacherTargetService {
    @Resource
    private ITeacherService teacherService;

    @Resource
    private ISiteConfigService siteConfigService;

    @Resource
    private ICourseClassService courseClassService;

    @Resource
    private IBusTeamService busTeamService;

    @Resource
    private IPeriodService periodService;

    @Override
    @Transactional
    public void insertByList(Long teacherId, String year, Integer targetType, List<TeacherTargetVo> teacherTargetVoList) {
        List<TeacherTarget> saveList=new ArrayList<TeacherTarget>();
        for (TeacherTargetVo teacherTargetVo:teacherTargetVoList){
            TeacherTarget teacherTarget=new TeacherTarget();
            BeanUtils.copyProperties(teacherTarget,teacherTargetVo);
            teacherTarget.setUpdateTime(TimeUtils.now());
            teacherTarget.setCreateTime(TimeUtils.now());
            if (teacherTarget.getTeacherTargetId()!=null){
                this.updateById(teacherTarget);
            }else{
                saveList.add(teacherTarget);
            }
        }
        if (saveList.size()>0){
            this.insertBatch(saveList);
        }
    }

    @Override
    public void deleteByTeacherIdAndTargetType(Long teacherId, String year, Integer targetType) {
        if(teacherId == null || year == null || targetType == null ){
            throw new NullPointerException();
        }
        Example example=TeacherTarget.createExample();
        Example.Criteria criteria=example.createCriteria();
        criteria.andEqualTo("teacherId",teacherId);
        criteria.andEqualTo("year",year);
        criteria.andEqualTo("targetType",targetType);
        this.deleteByExample(example);
    }

    @Override
    public List<TeacherTarget> findListByTeacherIdsAndPeriodIds(List<Long> teacherIds, List<Long> periodIdList, String year, List<Integer> targetTypeList) {
        if (teacherIds==null || teacherIds.size()<=0 ||  periodIdList==null || periodIdList.size()<=0 || targetTypeList==null || targetTypeList.size()<=0){
            return Collections.EMPTY_LIST;
        }
        Example<TeacherTarget> example=TeacherTarget.createExample();
        Example.Criteria criteria=example.createCriteria();
        criteria.andIn("teacherId", teacherIds);
        criteria.andIn("periodId",periodIdList);
        if (StringUtils.isNotEmpty(year)){
            criteria.andEqualTo("year",year);
        }
        criteria.andIn("targetType",targetTypeList);
        example.orderBy("teacherId");
        example.orderBy("targetType");
        example.orderBy("periodNo");
        return this.findListByExample(example);
    }

    @Override
    public Page<TeacherTargetResultVo> findPageByBusTeamIdAndYear(TeacherQueryVo teacherQueryVo, DataPermission dataPermission, String year, int pageNo, int pageSize) {
        if (teacherQueryVo.getAreaTeamId()==null){
            throw new BusException("区域必选");
        }
        teacherQueryVo.setAccessType(1);

        List<Period> periodList=periodService.findByYearAndAreaTeamId(teacherQueryVo.getAreaTeamId(),year);
        List<Long> periodIdList= BeanUtils.toList(periodList,"periodId");
        Page<Teacher> teacherPage=teacherService.findTeacherByQueryForPage(teacherQueryVo,dataPermission,pageNo,pageSize);
        List<Teacher> teacherList=teacherPage.getRecords();
        List<TeacherTargetResultVo> teacherTargetResultVoList=new ArrayList<TeacherTargetResultVo>();
        Page<TeacherTargetResultVo> teacherTargetResultVoPage= Utils.newPage(teacherPage);
        if (periodIdList.size()<=0){
            teacherTargetResultVoPage.setRecords(teacherTargetResultVoList);
            return teacherTargetResultVoPage;
        }

        if (teacherList!=null && teacherList.size()>0){
            String targetTypeJson = siteConfigService.getConfigValueFromCache("teacher_target_types");
            List<TargetTypeDetailVo> targetTypeDetailVos = JSONArray.parseArray(targetTypeJson, TargetTypeDetailVo.class);
            List<Long> teacherIds=BeanUtils.toList(teacherList,"teacherId");
            Map<Long,Teacher> teacherMap=BeanUtils.toMap(teacherList,"teacherId");
            List<Integer> targetTypes=BeanUtils.toList(targetTypeDetailVos,"targetType");
            Map<Integer,TargetTypeDetailVo> targetTypeDetailVoMap=BeanUtils.toMap(targetTypeDetailVos,"targetType");
            List<TeacherTarget> teacherTargets=this.findListByTeacherIdsAndPeriodIds(teacherIds,periodIdList,year,targetTypes);
            Map<Long,List<TeacherTarget>> resultMap=BeanUtils.toGroup(teacherTargets,"teacherId");

            List<TeacherTarget> saveList=new ArrayList<TeacherTarget>();
            for (Teacher teacher:teacherList){
                Long teacherId=teacher.getTeacherId();
                List<TeacherTarget> teacherTargetList=resultMap.get(teacherId);
                Map<Integer,List<TeacherTarget>> subMap=BeanUtils.toGroup(teacherTargetList,"targetType");
                for (TargetTypeDetailVo targetTypeDetailVo:targetTypeDetailVos){
                    if (subMap.containsKey(targetTypeDetailVo.getTargetType())){
                        List<TeacherTarget> tempList=subMap.get(targetTypeDetailVo.getTargetType());
                        List<Long> havePeriodIds=BeanUtils.toList(tempList,"periodId");
                        for (Period period:periodList){
                            if (!havePeriodIds.contains(period.getPeriodId())){
                                TeacherTarget teacherTarget=new TeacherTarget();
                                teacherTarget.setTeacherId(teacherId);
                                teacherTarget.setYear(year);
                                teacherTarget.setTargetType(targetTypeDetailVo.getTargetType());
                                teacherTarget.setCreateTime(TimeUtils.now());
                                teacherTarget.setUpdateTime(TimeUtils.now());
                                teacherTarget.setPeriodId(period.getPeriodId());
                                teacherTarget.setPeriodNo(period.getPeriodNo());
                                saveList.add(teacherTarget);
                            }
                        }
                    }else {
                        for (Period period:periodList){
                            TeacherTarget teacherTarget = new TeacherTarget();
                            teacherTarget.setTeacherId(teacherId);
                            teacherTarget.setYear(year);
                            teacherTarget.setTargetType(targetTypeDetailVo.getTargetType());
                            teacherTarget.setCreateTime(TimeUtils.now());
                            teacherTarget.setUpdateTime(TimeUtils.now());
                            teacherTarget.setPeriodId(period.getPeriodId());
                            teacherTarget.setPeriodNo(period.getPeriodNo());
                            saveList.add(teacherTarget);
                        }
                    }
                }
            }
            if (saveList.size()>0){
                this.insertBatch(saveList);
            }
            List<TeacherTarget> resultList=this.findListByTeacherIdsAndPeriodIds(teacherIds,periodIdList,year,targetTypes);
            Map<Long,List<TeacherTarget>> realResultMap=BeanUtils.toGroup(resultList,"teacherId");
            Iterator<Map.Entry<Long, List<TeacherTarget>>> resultEntries = realResultMap.entrySet().iterator();
            while(resultEntries.hasNext()){
                Map.Entry<Long, List<TeacherTarget>> entry = resultEntries.next();
                Long teacherId=entry.getKey();
                TeacherTargetResultVo teacherTargetResultVo=new TeacherTargetResultVo();
                teacherTargetResultVo.setTeacherId(teacherId);
                teacherTargetResultVo.setTeacherName(teacherMap.get(teacherId)==null?null:teacherMap.get(teacherId).getTeacherName());
                teacherTargetResultVo.setYear(year);
                List<TeacherTarget> subTeacherTargetList=entry.getValue();
                List<TeacherTargetDetailVo> teacherTargetDetailVoList=new ArrayList<TeacherTargetDetailVo>();
                Map<Integer,List<TeacherTarget>> subMap=BeanUtils.toGroup(subTeacherTargetList,"targetType");
                Iterator<Map.Entry<Integer, List<TeacherTarget>>> subResultEntries = subMap.entrySet().iterator();
                while (subResultEntries.hasNext()){
                    Map.Entry<Integer, List<TeacherTarget>> subEntry = subResultEntries.next();
                    TeacherTargetDetailVo teacherTargetDetailVo=new TeacherTargetDetailVo();
                    teacherTargetDetailVo.setTeacherId(teacherId);
                    teacherTargetDetailVo.setYear(year);
                    Integer targetType=subEntry.getKey();
                    List<TeacherTarget> subList=subEntry.getValue();
                    teacherTargetDetailVo.setTargetType(targetType);
                    teacherTargetDetailVo.setList(subList);
                    teacherTargetDetailVo.setTargetName(targetTypeDetailVoMap.get(targetType)==null?null:targetTypeDetailVoMap.get(targetType).getTargetName());
                    teacherTargetDetailVoList.add(teacherTargetDetailVo);
                }
                teacherTargetResultVo.setList(teacherTargetDetailVoList);
                Collections.sort(teacherTargetDetailVoList, new Comparator<TeacherTargetDetailVo>() {
                    public int compare(TeacherTargetDetailVo o1,
                                       TeacherTargetDetailVo o2) {
                        return (o1.getTargetType()).toString().compareTo(o2.getTargetType().toString());
                    }
                });
                teacherTargetResultVoList.add(teacherTargetResultVo);
            }
        }
        //Map<Long,List<TeacherTargetResultVo>> map=BeanUtils.toGroup(teacherTargetResultVoList,"teacherId");

        teacherTargetResultVoPage.setRecords(teacherTargetResultVoList);

        return  teacherTargetResultVoPage;
    }

    @Override
    public List<TeacherTarget> findListByTeacherIdsAndPeriodId(List<Long> teacherIds, Long periodId) {
        if (teacherIds==null || teacherIds.size()<=0){
            return Collections.EMPTY_LIST;
        }
        Example<TeacherTarget> example=TeacherTarget.createExample();
        Example.Criteria criteria=example.createCriteria();
        criteria.andIn("teacherId", teacherIds);
        criteria.andEqualTo("periodId",periodId);
        return this.findListByExample(example);
    }

    @Override
    public List<TeacherTarget> findListByTeachersAndPeriodIds(List<Long> teacherIds, List<Long> periodIds) {
        if (teacherIds==null || teacherIds.size()<=0 || periodIds==null || periodIds.size()<=0){
            return Collections.EMPTY_LIST;
        }
        Example<TeacherTarget> example=TeacherTarget.createExample();
        Example.Criteria criteria=example.createCriteria();
        criteria.andIn("teacherId", teacherIds);
        criteria.andIn("periodId",periodIds);
        return this.findListByExample(example);
    }

    @Override
    public List<TeacherTarget> findTeacherTargetByPeriodIdsAndTargetTypes(List<Long> periodIds, List<Integer> targetTypes) {
        if (periodIds==null || periodIds.size()<=0 || targetTypes==null || targetTypes.size()<=0){
            return Collections.EMPTY_LIST;
        }
        Example<TeacherTarget> example=TeacherTarget.createExample();
        Example.Criteria criteria=example.createCriteria();
        criteria.andIn("periodId", periodIds);
        criteria.andIn("targetType",targetTypes);
        return this.findListByExample(example);
    }
}